//
//  CutImage.cpp
//  opencv
//
//  Created by Minsky on 2017/8/16.
//  Copyright © 2017年 Minsky. All rights reserved.
//

#include "CutImage.hpp"
#include<math.h>


using namespace cv;
using namespace std;
//void cutImage(Mat src , int m,int n ,int x,int y, Mat& dst);
vector<Mat> read_images_in_folder(cv::String pattern);
vector<Mat> rename_images(cv::String pattren);
void save_txt(cv::String path);
vector<Mat> flip2(cv::String pattern);
vector<Mat> gradientcal(cv::String pattern);
vector<Mat> addNoise(cv::String pattern);
vector<Mat> batchNor(cv::String pattern);
Mat flip1(Mat src);
Mat flip3(Mat src);
void txt2image();

void fillRect(cv::Mat src,cv::Rect r,cv::Scalar color)
{
    cv::Point points[1][4];
    points[0][0]=cv::Point(r.x,r.y);
    points[0][1]=cv::Point(r.x+r.width,r.y);
    points[0][2]=cv::Point(r.x+r.width,r.y+r.height);
    points[0][3]=cv::Point(r.x,r.y+r.height);
    
    const cv::Point* ppt[1]={points[0]};
    int npt[] ={4};
    cv::fillPoly(src, ppt, npt, 1, color);

}

int main()
{

    //String path_dir = "/Users/new/Desktop/first_train_test/scratch/train/";
    //save_txt(path_dir);
//    String path = "/Users/new/Documents/JLIFE/project/HUAWEI-Server/scratchDL/SeventhModel/convolution/data/test/2/scratch_33949.png";
//    Mat src = imread("/Users/new/Documents/JLIFE/project/HUAWEI-Server/scratchDL/SeventhModel/convolution/data/test/2/scratch_33949.png",0);
//    Mat mask(src.size(),CV_8UC1,Scalar::all(0));
//    Rect b(0,0,100,100);
//    Rect c(100,100,50,50);
//    fillRect(mask, b, Scalar::all(255));
//    fillRect(mask,c,Scalar::all(255));
//    int max=2592;
//    int min=200;
//    float result = cvCeil(max/min);
//    std::cout<<result;
    
    //mask(b)=200;
//    for(int i=b.x;i<b.x+b.width;i++)
//    {
//        for(int j=b.y;j<b.y+b.height;j++)
//        {
//            mask(b).ptr<uchar>(i)[j] = 255;
//            
//        }
//    }
//    Mat mask1(src.size(),CV_8UC1,Scalar::all(0));
//    for(int i=c.x;i<c.x+c.width;i++)
//    {
//        for(int j=c.y;j<c.y+c.height;j++)
//        {
//            mask1(c).ptr<uchar>(i)[j] = 255;
//        }
//    }
//    Mat src1= src-mask;
//    imshow("aaaa",mask);
//    imshow("src",src1);
//    waitKey(0);
    //vector<Mat>images=flip2(path);
     //vector<Mat> images = read_images_in_folder(path);
    //vector<Mat> images = rename_images(path);
    //Mat srcImage = imread("/Users/new/Desktop/train-200x200/scratch_1_1_2_.png");
    //Mat dstImage;
    //dstImage = flip1(srcImage);
    //cutImage(srcImage, 256, 0, 0, dstImage);
    //imshow("dst", dstImage);
   // waitKey(0);
    //txt2image();
    string path = "C:/Users/liwenjun/Desktop/5/*.png";
    //vector<Mat> images = read_images_in_folder(path);
   vector<Mat> images =  flip2(path);
	//vector<Mat> images = gradientcal(path);
	//vector<Mat> images = addNoise(path);
    //rename_images(path);
	//vector<Mat> images = batchNor(path);
    
    printf("done.........................");
    return 0;
}

void cutImage(Mat src , int m,int n ,int x,int y, Mat& dst)
{
    Rect Roi;
    Roi.width = m;
    Roi.height = n;
    Roi.x = x;
    Roi.y = y;
    dst = src(Roi);
}
vector<Mat> read_images_in_folder(cv::String pattern)
{
    vector<cv::String> fn;
    glob(pattern, fn, false);
    int width = 200;
    int height = 200;
    char file_dst[100] = "";
    int index_y=0,index_x=0;
    vector<Mat> images;
    size_t count = fn.size(); //number of png files in images folder
    for (int i = 0; i < count; i++)
    {
        int y_max = std::floor(imread(fn[i],0).rows * 2/ height)-1;
        int x_max = std::floor(imread(fn[i],0).cols * 2/width)-1;
        //std::cout<<y_max<<" "<<x_max;
        for(int y  = 0;y <= y_max ; ++y)
        {
			if (y < y_max)
			{
				index_y = y*height / 2;
			}
			else 
			{
				index_y = imread(fn[i], 0).rows - height;
			}
            for(int x = 0; x <= x_max; ++x)
            {
                Mat dst;
                if(x<x_max)
                {
                   index_x = x * width/2;
                }
                else
                {
                    index_x = imread(fn[i],0).cols - width;
                }
                cutImage(imread(fn[i],0), width, height, index_x, index_y, dst);
                images.push_back(dst);
               // imshow("dst",dst);
               // waitKey(0);
                sprintf(file_dst, "C:/Users/liwenjun/Desktop/2/normal_a23_%d_%d.png",(index_x),(index_y));
                string strFileDst = string(file_dst);
                imwrite(strFileDst, dst);
            }
        }
     
    }
    return images;
}
vector<Mat> rename_images(cv::String pattren)
{
    vector<cv::String> fn;
    glob(pattren, fn,false);
    vector<Mat> images;
    size_t count = fn.size();
    char file_dst[100] = "";
    for(int i =0; i<count ; ++i)
    {
        sprintf(file_dst, "/Volumes/LACIE SHARE/tu/2/scratch_v_%d.png",(i+1));
        imwrite(file_dst, imread(fn[i],0));
        images.push_back(imread(fn[i],0));
    }
    return images;
}




Mat flip1(Mat src)
{
    Mat g_map_x,g_map_y,dst;
    g_map_x.create(src.size(), CV_32FC1);
    g_map_y.create(src.size(), CV_32FC1);
    for(int i=0;i<src.rows;++i)
    {
    for(int j=0;j<src.cols;++j)
        {
            g_map_x.ptr<float>(i)[j]=static_cast<float>(src.cols-j);
            g_map_y.ptr<float>(i)[j]=static_cast<float>(i);
        }
    }
    remap(src,dst,g_map_x,g_map_y,INTER_LINEAR);
    //imwrite("/Users/new/Desktop/6/scratch_1.png",dst);
    return dst;
}

Mat flip3(Mat src)
{
    Mat dst;
    transpose(src, dst);
    return dst;

}
vector<Mat> flip2(cv::String pattern)
{
    vector<Mat> images;
    vector<cv::String> fn;
    glob(pattern,fn,false);
     size_t count = fn.size();
    char file_dst[100] = "";
    for(int i=0;i<count;++i)
    {
     sprintf(file_dst, "C:/Users/liwenjun/Desktop/6/normal_f_%d.png",(i+2001));
        Mat dst;
        dst = flip1(imread(fn[i],0));
        imwrite(file_dst, dst);
        images.push_back(dst);
    }
    return images;
}

void txt2image()
{
    ifstream myfile("/Users/new/Documents/JLIFE/project/HUAWEI-Server/scratchDL/FourthModel/C2-200x200-back/data/resultback/scratch->right/scratch->right.txt");
    string temp;
    string save_dir="/Users/new/Documents/JLIFE/project/HUAWEI-Server/scratchDL/FourthModel/C2-200x200-back/data/resultback/scratch->right/";
    string file_dir="/Users/new/Documents/JLIFE/project/HUAWEI-Server/scratchDL/FourthModel/C2-200x200-back/data/test/scratchback/";
    if(myfile)
    {
        while(getline(myfile,temp,' '))
        {
            size_t len = temp.length();
            int start=0,end=0,i=0;
            
            while(i<len)
            {
                string filename={};
                
                while(temp[i]!='\n')
                {
                    if(temp[i]=='b')
                    {
                        
                        start = i+2;
                    }
                    if(temp[i]=='g')
                    {
                        end = i+1;
                    }
                    
                    int n=end-start;
                    if(n>0)
                    {
                    filename=temp.substr(start,n);
                    }
                    i++;
                }
                i++;
                Mat image=imread(file_dir+filename);
                imwrite(save_dir+filename, image);
                
                
            }
            
            
            
        }
    }
    else{
        cout<<"No Such File!~"<<endl;
    }
    
}


//高斯模糊
vector<Mat> gradientcal(cv::String pattern)
{
	vector<Mat> images;
	vector<cv::String> fn;
	glob(pattern, fn, false);
	size_t count = fn.size();
	char file_dst[100] = "";
	for (int i = 0; i<count; ++i)
	{
		sprintf(file_dst, "C:/Users/liwenjun/Desktop/3/normal_%d.png", (i + 0));
		Mat dst, gaux, gauy;
		Mat sobelx;
		Mat sobely;
		GaussianBlur(imread(fn[i], 0), dst, Size(5, 5), 0, 0);
		//GaussianBlur(imread(fn[i], 0), gaux, Size(7, 7), 0, 0);
		//GaussianBlur(imread(fn[i], 0), gauy, Size(7, 7), 0, 0);
		//Sobel(gaux, sobelx, CV_32F, 1, 0, 3);
		//Sobel(gauy, sobely, CV_32F, 0, 1, 3);
		//convertScaleAbs(sobelx, sobelx);
		//convertScaleAbs(sobely, sobely);
		//addWeighted(sobelx, 0.5, sobely, 0.5, 0, dst);
		imwrite(file_dst, dst);
		images.push_back(dst);
	}
	return images;
}

//高斯随机分布
double generateGaussianNoise(double mu, double sigma)
{
	//定义小值  
	const double epsilon = numeric_limits<double>::min();
	static double z0, z1;
	static bool flag = false;
	flag = !flag;
	//flag为假构造高斯随机变量X  
	if (!flag)
		return z1 * sigma + mu;
	double u1, u2;
	//构造随机变量  
	do
	{
		u1 = rand() * (1.0 / RAND_MAX);
		u2 = rand() * (1.0 / RAND_MAX);
	} while (u1 <= epsilon);
	//flag为真构造高斯随机变量  
	z0 = sqrt(-2.0*log(u1))*cos(2 * CV_PI*u2);
	z1 = sqrt(-2.0*log(u1))*sin(2 * CV_PI*u2);
	return z0*sigma + mu;
}

//为图像添加高斯噪声  
Mat addGaussianNoise(Mat &srcImag)
{
	Mat dstImage = srcImag.clone();
	int channels = dstImage.channels();
	int rowsNumber = dstImage.rows;
	int colsNumber = dstImage.cols*channels;
	//判断图像的连续性  
	if (dstImage.isContinuous())
	{
		colsNumber *= rowsNumber;
		rowsNumber = 1;
	}
	for (int i = 0; i < rowsNumber; i++)
	{
		for (int j = 0; j < colsNumber; j++)
		{
			//添加高斯噪声  
			int val = dstImage.ptr<uchar>(i)[j] +
				generateGaussianNoise(1.0, 0.2) * 8;
			if (val < 0)
				val = 0;
			if (val>255)
				val = 255;
			dstImage.ptr<uchar>(i)[j] = (uchar)val;
		}
	}
	return dstImage;
}

//椒盐噪声
Mat addSaltNoise(const Mat srcImage, int n)
{
	Mat dstImage = srcImage.clone();
	for (int k = 0; k < n; k++)
	{
		//随机取值行列  
		int i = rand() % dstImage.rows;
		int j = rand() % dstImage.cols;
		//图像通道判定  
		if (dstImage.channels() == 1)
		{
			dstImage.at<uchar>(i, j) = 255;       //盐噪声  
		}
		else
		{
			dstImage.at<Vec3b>(i, j)[0] = 255;
			dstImage.at<Vec3b>(i, j)[1] = 255;
			dstImage.at<Vec3b>(i, j)[2] = 255;
		}
	}
	for (int k = 0; k < n; k++)
	{
		//随机取值行列  
		int i = rand() % dstImage.rows;
		int j = rand() % dstImage.cols;
		//图像通道判定  
		if (dstImage.channels() == 1)
		{
			dstImage.at<uchar>(i, j) = 0;     //椒噪声  
		}
		else
		{
			dstImage.at<Vec3b>(i, j)[0] = 0;
			dstImage.at<Vec3b>(i, j)[1] = 0;
			dstImage.at<Vec3b>(i, j)[2] = 0;
		}
	}
	return dstImage;
}

vector<Mat> addNoise(cv::String pattern)
{
	vector<Mat> images;
	vector<cv::String> fn;
	glob(pattern, fn, false);
	size_t count = fn.size();
	char file_dst[100] = "";
	for (int i = 0; i<count; ++i)
	{
		sprintf(file_dst, "C:/Users/liwenjun/Desktop/1/normal_%d.png", (i + 0));
		Mat dst, gaux, gauy;
		Mat sobelx;
		Mat sobely;
		dst = addGaussianNoise(imread(fn[i], 0));//gaussian
		//dst = addSaltNoise(imread(fn[i], 0), 100);//salt
		//GaussianBlur(imread(fn[i], 0), gaux, Size(7, 7), 0, 0);
		//GaussianBlur(imread(fn[i], 0), gauy, Size(7, 7), 0, 0);
		//Sobel(gaux, sobelx, CV_32F, 1, 0, 3);
		//Sobel(gauy, sobely, CV_32F, 0, 1, 3);
		//convertScaleAbs(sobelx, sobelx);
		//convertScaleAbs(sobely, sobely);
		//addWeighted(sobelx, 0.5, sobely, 0.5, 0, dst);
		imwrite(file_dst, dst);
		images.push_back(dst);
	}
	return images;
}


vector<Mat> batchNor(cv::String pattern)
{
	vector<Mat> images;
	vector<cv::String> fn;
	glob(pattern, fn, false);
	size_t count = fn.size();
	char file_dst[100] = "";
	for (int i = 0; i<count; ++i)
	{
		sprintf(file_dst, "C:/Users/liwenjun/Desktop/00/normal_%d.png", (i + 0));
		Mat dst;
		cv::Scalar mean;
		cv::Scalar dev;
		cv::meanStdDev(imread(fn[i],0), mean, dev);
		float input_mean = mean.val[0];
		float input_std = dev.val[0];
		input_std = std::sqrt(input_std);
		input_std = std::max<float>(input_std, 0.000001);
		imread(fn[i], 0).convertTo(dst, CV_8UC1, 1/input_std, -input_mean/input_std);
		//normalize(imread(fn[i],0),dst,NORM_L1);
		
		imwrite(file_dst, dst);
		images.push_back(dst);
	}
	return images;
}





